home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- * Language : Turbo C 2.0 *
- * Logfile : rz.c *
- * Project : Comms library. *
- * Date : 24 Jan 90 *
- * Revision : 1.1 GT PC version. *
- * 07 Mar 90 : 1.2 GT Background transfer. *
- * 25 Oct 92 : 1.3 GT KA9Q mods. *
- * 30 Jan 93 : 1.4 GT Fix KA9Q background transfer. *
- * 20 Feb 93 : 1.5 GT Bump HOWMANY to 2048. *
- * 21 Feb 93 : 1.6 GT Allocate buffer on heap. *
- * 08 May 93 : 1.7 GT Fix warnings. *
- *****************************************************************************
- * Purpose : File receive driver. *
- *****************************************************************************
- * : This module is based on the equivalent module in the *
- * : 31 Aug 87 version of rz/sz. *
- * $Id: rz.c 1.5 93/07/16 11:49:53 ROOT_DOS Exp $
- *
- * ATARI Version by David Nash - dnash@chaos.demon.co.uk
- *
- ****************************************************************************/
-
- #include <io.h>
- #include <fcntl.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <signal.h>
- #include <setjmp.h>
- #include <ctype.h>
- #include <time.h>
- #include <string.h>
- #include <process.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <dos.h>
- #ifdef ATARI
- #include <ext.h>
- #endif
- #include "zmodem.h"
- #include "sz.h"
- #include "rbsb.h" /* most of the system dependent stuff here */
- #include "zm.h"
- #include "global.h"
- #ifdef DEBUGZ
- #include "tty.h"
- #endif
-
-
- /*
- * Max value for HOWMANY is 255.
- * A larger value reduces system overhead but may evoke kernel bugs.
- * 133 corresponds to an XMODEM/CRC sector
- */
-
- #ifndef HOWMANY
- #define HOWMANY 2048 /* was 133 */
- #endif
-
- #undef RETRYMAX
- #define RETRYMAX 5
-
- #define UNIXFILE 0x8000 /* the S_IFREG file mask bit for stat */
- #define DEFBYTL 2000000000L /* default rx file size */
- #define CANBREAK
-
- static int fout;
- static int Eofseen; /* indicates cpm eof (^Z) has been received */
-
- int Readnum = HOWMANY; /* Number of bytes to ask for in read () from
- modem */
-
- static long Bytesleft; /* number of bytes of incoming file left */
- static long Modtime; /* Unix style mod time for incoming file */
- static short Filemode; /* Unix style mode for incoming file */
- static char Pathname[PATHLEN];
-
- static int Batch = 0;
- static int MakeLCPathname = TRUE; /* make received pathname lower case */
- static int Nflag = 0; /* Don't really transfer files */
- static int Rxbinary = FALSE; /* receive all files in bin mode */
- static int Rxascii = FALSE; /* receive files in ascii (translate) mode */
- static int Thisbinary; /* current file is to be received in bin mode */
- static int rz_blklen; /* record length of received packets */
- static char secbuf[KSIZE + 1];
- #if 0
- static char linbuf[HOWMANY];
- #endif
- static char *linbuf = 0; /* -> receive buffer */
- int Lleft = 0; /* number of characters in linbuf */
- static int Filcnt = 0; /* no of files transferred */
-
- #if 0
- time_t timep[2];
- #endif
- static int nocommand = FALSE; /* TRUE - disallow remote commands */
-
- static int tryzhdrtype = ZRINIT; /* Header type to send corresponding to Last
- rx close */
-
-
- /****************************************************************************
- * Local prototypes. *
- ****************************************************************************/
-
- #if 0
- static void bibi (int n);
- #endif
- static void chkinvok (char protocol);
- static void purgeline (void);
- static void uncaps (char *s);
- static int IsAnyLower (char *s);
- static void canit (void);
- static void report (int sct);
- static void checkpath (char *name);
- static int tryz (void);
- static int rzfiles (void);
- static int rzfile (void);
- static void zmputs (char *s);
- static int closeit (void);
- static void ackbibi (void);
- static int sys2 (char *s);
- static void exec2 (char *s);
- static long getfree (void);
- static int wcreceive (int argc, char **argp);
- static int wcrxpn (char *rpn);
- static int wcrx (void);
- static int wcgetsec (char *rxbuf, int maxtime);
- static int procheader (char *name);
- static int putsec (char *buf, int n);
-
-
- /****************************************************************************
- * getfree *
- * Routine to calculate the free bytes on the current file system. *
- * ~0 means many free bytes (unknown). *
- ****************************************************************************/
-
- static long getfree (void)
- {
- return (~0L); /* many free bytes ... */
- } /* static long getfree (void) */
-
-
- #if 0
- /****************************************************************************
- * bibi *
- * Called by signal interrupt or terminate to clean things up. *
- ****************************************************************************/
- static void bibi (int n)
- {
- n = n;
- if (_Zmodem)
- {
- #ifdef DEBUGZ
- _tout ("\r\n\nbibi: calling zmputs (_Attn)\r\n");
- #endif
- zmputs (_Attn);
- }
-
- canit ();
- _zperr_ ("Interrupted\n");
- closeit ();
- #ifdef DEBUGZ
- _tout ("bibi: doing longjmp (_tohere, -1)\r\n");
- #endif
- longjmp (_tohere, -1);
- } /* static void bibi (int n) */
- #endif
-
-
- /****************************************************************************
- * _getfile *
- * Receives file(s). Returns 0 if successful. *
- ****************************************************************************/
-
- int _getfile (int s, char protocol, char *options, char *filename,
- void (*reporter) (int type, void *data))
- {
- char *cp;
- int npats;
- char **patts;
- int exitcode = 0;
- #if 0
- void (*sigint_sav) (int);
- void (*sigterm_sav) (int);
- #endif
-
- /* Initialise global variables. */
-
- _z_socket = s;
- Batch = 0;
- _do_report = _zperr;
- Filcnt = 0;
- Lleft = 0;
- MakeLCPathname = TRUE;
- Nflag = 0;
- nocommand = FALSE;
- _Nozmodem = 0;
- _Quiet = 0;
- Readnum = HOWMANY;
- Rxascii = FALSE;
- Rxbinary = FALSE;
- _Rxtimeout = 100;
- _sending = FALSE;
- tryzhdrtype = ZRINIT;
- _Verbose = 0;
- _Wcsmask = 0377;
- _Zmodem = 0;
- _Zrwindow = 1400;
-
- chkinvok (protocol); /* choose protocol */
- npats = 0;
-
- /* Parse options. */
-
- cp = options;
- while (*cp != '\0')
- {
- switch (*cp++)
- {
- case '7': /* strip top bit */
- _Wcsmask = 0177;
-
- case 'a': /* ASCII transfer */
- Rxascii = TRUE;
- break;
-
- case 'b': /* binary transfer */
- Rxbinary = TRUE;
- break;
-
- case 'c': /* XMODEM/CRC */
- _Crcflg = TRUE;
- break;
-
- case 'D': /* fake file transfer */
- Nflag = TRUE;
- break;
-
- case 'i': /* disallow remote command */
- nocommand = TRUE;
- break;
-
- case 'e': /* escape ctl chars */
- _Zctlesc = 1;
- break;
-
- case 'p': /* 'protect' option */
- _Lzmanag = ZMPROT;
- break;
-
- case 'q': /* quiet */
- _Quiet = TRUE;
- _Verbose = 0;
- break;
-
- case 't': /* change timeout */
- sscanf (cp, "%d", &_Rxtimeout);
- if (_Rxtimeout < 10 || _Rxtimeout > 1000)
- return (ERROR);
-
- cp = _stbnb (cp);
- break;
-
- case 'w': /* window size */
- sscanf (cp, "%d", &_Zrwindow);
- cp = _stbnb (cp);
- break;
-
- case 'u': /* no lower case convert */
- MakeLCPathname = FALSE;
- break;
-
- case 'v': /* debug info */
- ++_Verbose;
- break;
-
- default:
- return (ERROR);
- } /* switch (*cp++) */
-
- } /* while (*cp != '\0') */
-
- /* Get filename. */
-
- if (filename != NULL)
- {
- npats = 1;
- patts = &filename;
- }
-
- if (npats > 1)
- return (ERROR);
-
- if (Batch && npats)
- return (ERROR);
-
- /* Get reporter function */
-
- if (reporter != NULL)
- _do_report = reporter; /* user supplied fn */
-
- #if 0
- if (_Verbose)
- {
- if ((_zperr_handle = open (LOGFILE,
- O_CREAT | O_APPEND | O_WRONLY | O_TEXT,
- S_IFREG | S_IWRITE)) == -1)
- {
- char buff[80];
-
- sprintf (buff, "Can't open log file %s: %s\n",
- LOGFILE, strerror (errno));
- (*_do_report) (2, buff);
- (*_do_report) (3, &Filcnt); /* report no of files */
- return (ERROR);
- }
-
- _do_report = _zperr; /* use default reporter */
- }
- #endif
-
- if (!_Quiet)
- {
- if (_Verbose == 0)
- _Verbose = 2;
-
- }
-
- #if 0
- if ((sigint_sav = signal (SIGINT, bibi)) == SIG_IGN)
- signal (SIGINT, SIG_IGN);
- else
- signal (SIGINT, bibi);
-
- #endif
-
- #if 0
- sigint_sav = signal (SIGINT, bibi);
- sigterm_sav = signal (SIGTERM, bibi);
- #endif
-
- /* Set up escape routes. */
-
- if (setjmp (_tohere) != 0)
- {
- #ifdef DEBUGZ
- _tout ("getfile: exiting via _tohere jump\r\n");
- #endif
- (*_do_report) (3, &Filcnt); /* report files transferred */
- #if 0
- signal (SIGINT, sigint_sav);
- signal (SIGTERM, sigterm_sav);
- (void) close (_zperr_handle);
- #endif
- return (-2); /* user abort */
- }
-
- if (setjmp (_nocarrier) != 0)
- {
- #ifdef DEBUGZ
- _tout ("getfile: exiting via _nocarrier jump\r\n");
- #endif
- (*_do_report) (3, &Filcnt); /* report files transferred */
- #if 0
- signal (SIGINT, sigint_sav);
- signal (SIGTERM, sigterm_sav);
- (void) close (_zperr_handle);
- #endif
- return (-3); /* lost carrier */
- }
-
- /* Get the file(s). */
-
- if (wcreceive (npats, patts) == ERROR)
- {
- exitcode = 0200;
- canit ();
- }
-
- if (exitcode && !_Zmodem) /* Bellow again with all thy might. */
- canit ();
-
- if (!_Quiet)
- _say ("\n");
-
- (*_do_report) (3, &Filcnt); /* report files transferred */
- #if 0
- signal (SIGINT, sigint_sav);
- signal (SIGTERM, sigterm_sav);
- (void) close (_zperr_handle);
- #endif
- return (exitcode);
- } /* int _getfile (int s, char protocol, char *options, char *filename,
- void (*reporter) (int type, void *data)) */
-
-
- /****************************************************************************
- * wcreceive *
- * Let's receive something already. *
- ****************************************************************************/
-
- #if 0
- static char *rbmsg = "Ready to receive.\n"
- "To begin transfer, issue the send command "
- "to your modem program\r\n";
- #endif
-
- static int wcreceive (int argc, char **argp)
- {
- int c;
-
- if (Batch || argc == 0)
- {
- /* ZMODEM / YMODEM BATCH */
-
- _Crcflg = (_Wcsmask == 0377);
- #if 0
- if (!_Quiet)
- _say (rbmsg);
-
- #endif
-
- if ((c = tryz ()) != 0)
- {
- if (c == ZCOMPL)
- return OK;
-
- if (c == ERROR)
- goto fubar;
-
- c = rzfiles ();
- if (c)
- goto fubar;
-
- } /* if ((c = tryz ()) != 0) */
- else
- {
- for (;;)
- {
- if (wcrxpn (secbuf) == ERROR)
- goto fubar;
-
- if (secbuf[0] == 0)
- return OK;
-
- if (procheader (secbuf) == ERROR)
- goto fubar;
-
- if (wcrx () == ERROR)
- goto fubar;
-
- } /* for (;;) */
-
- } /* else */
-
- } /* if (Batch || argc == 0) */
- else
- {
- /* XMODEM */
-
- Bytesleft = DEFBYTL;
- Filemode = 0;
- Modtime = 0L;
-
- procheader ("");
- strcpy (Pathname, *argp);
- checkpath (Pathname);
- (*_do_report) (0, Pathname);
- _say ("\nReady to receive %s\r\n", Pathname);
- if ((fout = open (Pathname,
- O_CREAT | O_TRUNC | O_WRONLY | O_BINARY,
- S_IFREG | S_IWRITE)) == -1)
- return ERROR;
-
- if (wcrx () == ERROR)
- goto fubar;
-
- ++Filcnt;
- } /* else */
-
- return OK;
-
- /* Transfer failed - clean up. */
-
- fubar:
- canit ();
- if (fout != -1)
- close (fout);
-
- return ERROR;
- } /* static int wcreceive (int argc, char **argp) */
-
-
- /****************************************************************************
- * wcrxpn *
- * Fetch a pathname from the other end as a C ctyle ASCIZ string. Length *
- * is indeterminate as long as less than rz_blklen. A null string *
- * represents no more files (YMODEM). *
- ****************************************************************************/
-
- static int wcrxpn (char *rpn)
- {
- int c;
-
- purgeline ();
-
- et_tu:
- _firstsec = TRUE;
- Eofseen = FALSE;
- _sendline (_Crcflg ? WANTCRC : NAK);
- Lleft = 0; /* Do read next time ... */
- while ((c = wcgetsec (rpn, 100)) != 0)
- {
- if (c == WCEOT)
- {
- _zperr_ ("Pathname fetch returned %d", c);
- _sendline (ACK);
- Lleft = 0; /* Do read next time ... */
- _readline (1);
- goto et_tu;
- }
-
- return ERROR;
- } /* while ((c = wcgetsec (rpn, 100)) != 0) */
-
- _sendline (ACK);
- return OK;
- } /* static int wcrxpn (char *rpn) */
-
-
- /****************************************************************************
- * wcrx *
- * Adapted from CMODEM13.C, written by Jack M Wierda and Roderick W Hart. *
- ****************************************************************************/
-
- static int wcrx (void)
- {
- int sectnum, sectcurr;
- char sendchar;
- int cblklen; /* bytes to dump this block */
-
- _firstsec = TRUE;
- sectnum = 0;
- Eofseen = FALSE;
- sendchar = (char) (_Crcflg ? WANTCRC : NAK);
-
- for (;;)
- {
- _sendline (sendchar); /* send it now, we're ready! */
- Lleft = 0; /* Do read next time ... */
- sectcurr = wcgetsec (secbuf, (sectnum & 0177) ? 50 : 130);
- report (sectcurr);
- if (sectcurr == (sectnum + 1 & _Wcsmask))
- {
- sectnum++;
- cblklen = Bytesleft > rz_blklen ? rz_blklen : (int) Bytesleft;
- if (putsec (secbuf, cblklen) == ERROR)
- return ERROR;
-
- if ((Bytesleft -= cblklen) < 0)
- Bytesleft = 0;
-
- sendchar = ACK;
- }
- else if (sectcurr == (sectnum & _Wcsmask))
- {
- _zperr_ ("Received dup Sector");
- sendchar = ACK;
- }
- else if (sectcurr == WCEOT)
- {
- if (closeit ())
- return ERROR;
-
- _sendline (ACK);
- Lleft = 0; /* Do read next time ... */
- return OK;
- }
- else if (sectcurr == ERROR)
- return ERROR;
- else
- {
- _zperr_ ("Sync Error");
- return ERROR;
- }
-
- } /* for (;;) */
-
- } /* static int wcrx (void) */
-
-
- /****************************************************************************
- * wcgetsec *
- * Fetches a Ward Christensen type sector. Returns sector number *
- * encountered or ERROR if valid sector not received, or CAN CAN received *
- * or WCEOT if eot sector. <maxtime> is timeout for first char, set to 4 *
- * seconds thereafter. NO ACK IS SENT IF SECTOR IS RECEIVED OK (Caller *
- * must do that when he is good and ready to get next sector). *
- ****************************************************************************/
-
- static int wcgetsec (char *rxbuf, int maxtime)
- {
- int checksum, wcj, firstch;
- unsigned short oldcrc;
- char *p;
- int sectcurr;
-
- for (_Lastrx = _errors = 0; _errors < RETRYMAX; _errors++)
- {
- if ((firstch = _readline (maxtime)) == STX)
- {
- rz_blklen = KSIZE;
- goto get2;
- }
-
- if (firstch == SOH)
- {
- rz_blklen = SECSIZ;
-
- get2:
- sectcurr = _readline (1);
- if ((sectcurr + (oldcrc = _readline (1))) == _Wcsmask)
- {
- oldcrc = checksum = 0;
- for (p = rxbuf, wcj = rz_blklen; --wcj >= 0;)
- {
- if ((firstch = _readline (1)) < 0)
- goto bilge;
-
- oldcrc = updcrc (firstch, oldcrc);
- checksum += (*p++ = (char) firstch);
- }
-
- if ((firstch = _readline (1)) < 0)
- goto bilge;
-
- if (_Crcflg)
- {
- oldcrc = updcrc (firstch, oldcrc);
- if ((firstch = _readline (1)) < 0)
- goto bilge;
-
- oldcrc = updcrc (firstch, oldcrc);
- if (oldcrc & 0xFFFF)
- _zperr_ ( "CRC");
- else
- {
- _firstsec = FALSE;
- return sectcurr;
- }
-
- } /* if (_Crcflg) */
- else if (((checksum - firstch) & _Wcsmask) == 0)
- {
- _firstsec = FALSE;
- return sectcurr;
- }
- else
- _zperr_ ( "Checksum");
-
- } /* if ((sectcurr + (oldcrc = _readline (1))) == _Wcsmask) */
- else
- _zperr_ ("Sector number garbled");
-
- } /* if (firstch == SOH) */
- else if (firstch == EOT && Lleft == 0) /* make sure eot really is
- eot and not just mixmash */
- return WCEOT;
- else if (firstch == CAN)
- {
- if (_Lastrx == CAN)
- {
- _zperr_ ("Sender CANcelled");
- return ERROR;
- }
- else
- {
- _Lastrx = CAN;
- continue;
- }
-
- } /* else if (firstch == CAN) */
- else if (firstch == ZTIMEOUT)
- {
- if (_firstsec)
- goto humbug;
-
- bilge:
- _zperr_ ( "TIMEOUT");
- }
- else
- _zperr_ ( "Got 0%o sector header", firstch);
-
- humbug:
- _Lastrx = 0;
- while (_readline (1) != ZTIMEOUT)
- ;
-
- if (_firstsec)
- {
- _sendline (_Crcflg ? WANTCRC : NAK);
- Lleft = 0; /* Do read next time ... */
- }
- else
- {
- maxtime = 40;
- _sendline (NAK);
- Lleft = 0; /* Do read next time ... */
- }
-
- } /* for (_Lastrx = _errors = 0; _errors < RETRYMAX; _errors++) */
-
- /* try to stop the bubble machine. */
-
- canit ();
- return ERROR;
- } /* static int wcgetsec (char *rxbuf, int maxtime) */
-
-
- /****************************************************************************
- * _readline *
- * This version of _readline is reasonably well suited for reading many *
- * characters (except, currently, for the Regulus version!). Timeout is *
- * in tenths of seconds. *
- ****************************************************************************/
-
- int _readline (int timeout)
- {
- int n;
- static char *cdq; /* pointer for removing chars from linbuf */
- time_t start; /* start for timeout */
-
- if (linbuf == 0)
- linbuf = mallocw (HOWMANY);
-
- if (--Lleft >= 0)
- {
- if (_Verbose > 8)
- {
- _say ("%02x ", *cdq & 0377);
- }
-
- return (*cdq++ & _Wcsmask);
- }
-
- n = timeout / 10;
- if (n < 2)
- n = 3;
-
- time (&start);
- if (_Verbose > 5)
- _vfile ("Calling read: alarm=%d Readnum=%d ", n, Readnum);
-
- _no_carrier ();
- while (1)
- {
- Lleft = _receive ((unsigned char *) (cdq = linbuf), Readnum);
- if (Lleft != 0)
- break; /* got something */
-
- if (time (NULL) >= start + n)
- {
- _zperr_ ("ZTIMEOUT");
- return (ZTIMEOUT);
- }
-
- }
-
- if (_Verbose > 5)
- {
- _say ("Read returned %d bytes\n", Lleft);
- }
-
- if (Lleft < 1)
- return ZTIMEOUT;
-
- --Lleft;
- if (_Verbose > 8)
- {
- _say ("%02x ", *cdq & 0377);
- }
-
- return (*cdq++ & _Wcsmask);
- } /* int _readline (int timeout) */
-
-
- /****************************************************************************
- * purgeline *
- * Purge the modem input queue of all characters. *
- ****************************************************************************/
-
- static void purgeline (void)
- {
- unsigned char c;
-
- Lleft = 0;
- while (_rdchk () > 0)
- _receive (&c, 1);
-
- } /* static void purgeline (void) */
-
-
- /****************************************************************************
- * procheader *
- * Process incoming file information header. *
- ****************************************************************************/
-
- static int procheader (char *name)
- {
- int openmode;
- char *p;
-
- /* set default parameters and overrides */
-
- (*_do_report) (0, name);
- openmode = O_CREAT | O_TRUNC | O_WRONLY | O_BINARY;
- Thisbinary = (!Rxascii) || Rxbinary;
- if (_Lzmanag)
- _zmanag = _Lzmanag;
-
- /* Process ZMODEM remote file management requests. */
-
- if (!Rxbinary && _zconv == ZCNL) /* Remote ASCII override */
- Thisbinary = 0;
-
- if (_zconv == ZCBIN) /* Remote Binary override */
- Thisbinary = TRUE;
- else if (_zmanag == ZMAPND)
- openmode = O_APPEND | O_WRONLY | O_BINARY;
-
- /* ZMPROT check for existing file */
-
- if (_zmanag == ZMPROT && (fout = open (name, O_RDONLY, S_IREAD)) != -1)
- {
- close (fout);
- return ERROR;
- }
-
- Bytesleft = DEFBYTL;
- Filemode = 0;
- Modtime = 0L;
-
- p = name + 1 + strlen (name);
- if (*p)
- {
- /* file coming from Unix or DOS system */
-
- sscanf (p, "%ld%lo%o", &Bytesleft, &Modtime, &Filemode);
- if (Filemode & UNIXFILE)
- ++Thisbinary;
-
- if (_Verbose)
- {
- _say ("Incoming: %s %ld %lo %o\n",
- name, Bytesleft, Modtime, Filemode);
- }
-
- } /* if (*p) */
- else
- {
- /* File coming from CP/M system */
-
- for (p = name; *p; ++p) /* change / to _ */
- if ( *p == '/')
- *p = '_';
-
- if ( *--p == '.') /* zap trailing period */
- *p = 0;
-
- } /* else */
-
- if (!_Zmodem && MakeLCPathname && !IsAnyLower (name))
- uncaps (name);
-
- strcpy (Pathname, name);
- if (_Verbose)
- {
- _say ("Receiving %s %s\n",
- name, Thisbinary ? "BIN" : "ASCII");
- }
-
- checkpath (name);
- if (Nflag)
- name = "nul"; /* send to bit bucket */
-
- if ((fout = open (name, openmode, S_IFREG | S_IWRITE)) == -1)
- {
- _vfile ("Can't open %s mode %x, %s\n",
- name, openmode, strerror (errno));
- return ERROR;
- }
-
- return OK;
- } /* static int procheader (char *name) */
-
-
- /****************************************************************************
- * putsec *
- * Writes the <n> characters of <buf> to receive file fout. If not in *
- * binary mode, carriage returns, and all characters starting with CPMEOF *
- * are discarded. *
- ****************************************************************************/
-
- static int putsec (char *buf, int n)
- {
- char *p, *q;
- char locbuf[KSIZE + 1];
- int qcount; /* no of chars in local buffer */
-
- if (Thisbinary)
- {
- write (fout, buf, n);
- #if 0
- for (p = buf; --n >= 0;)
- putc (*p++, fout);
-
- #endif
- }
- else
- {
- if (Eofseen)
- return OK;
-
- q = locbuf;
- qcount = 0;
- for (p = buf; --n >= 0; ++p)
- {
- #if 0
- /* We'll keep CR under MesS-DOS. */
-
- if (*p == '\r')
- continue;
-
- #endif
- if (*p == CPMEOF)
- {
- Eofseen = TRUE;
- return OK;
- }
-
- *q++ = *p; /* put byte in write buffer */
- qcount++;
- #if 0
- putc (*p ,fout);
- #endif
- } /* for (p = buf; --n >= 0; ++p) */
-
- if (qcount != 0)
- write (fout, locbuf, qcount);
-
- } /* else */
-
- return OK;
- } /* static int putsec (char *buf, int n) */
-
-
- /****************************************************************************
- * uncaps *
- * Make string <s> lower case. *
- ****************************************************************************/
-
- static void uncaps (char *s)
- {
- for (; *s; ++s)
- if (isupper (*s))
- *s = tolower (*s);
-
- } /* static void uncaps (char *s) */
-
-
- /****************************************************************************
- * IsAnyLower *
- * IsAnyLower returns TRUE if string s has lower case letters. *
- ****************************************************************************/
-
- static int IsAnyLower (char *s)
- {
- for (; *s; ++s)
- if (islower (*s))
- return TRUE;
-
- return FALSE;
- } /* static int IsAnyLower (char *s) */
-
-
- /****************************************************************************
- * canit *
- * Send cancel string to get the other end to shut up. *
- ****************************************************************************/
-
- static void canit (void)
- {
- #ifdef DEBUGZ
- _tout ("canit: calling _canit ()\r\n");
- #endif
- _canit ();
- Lleft = 0; /* Do read next time ... */
- #ifdef DEBUGZ
- _tout ("leaving canit ()\r\n");
- #endif
- } /* static void canit (void) */
-
-
- /****************************************************************************
- * report *
- * Print <sct>. *
- ****************************************************************************/
-
- static void report (int sct)
- {
- if (_Verbose > 1)
- _say ("%03d%c", sct, sct % 10 ? ' ' : '\r');
-
- } /* static void report (int sct) */
-
-
- /****************************************************************************
- * chkinvok *
- * Set chosen protocol. *
- ****************************************************************************/
-
- static void chkinvok (char protocol)
- {
- if (protocol == 'z')
- Batch = TRUE;
-
- if (protocol == 'y')
- Batch = _Nozmodem = TRUE;
-
- } /* static void chkinvok (char protocol) */
-
-
- /****************************************************************************
- * checkpath *
- * Totalitarian Communist pathname processing. *
- ****************************************************************************/
-
- static void checkpath (char *name)
- {
- /* No restrictions in this version. */
-
- name = name; /* silence compiler */
- } /* static void checkpath (char *name) */
-
-
- /****************************************************************************
- * tryz *
- * Initialize for Zmodem receive attempt, try to activate Zmodem sender. *
- * Handles ZSINIT frame. Return ZFILE if Zmodem filename received, -1 on *
- * error, ZCOMPL if transaction finished, else 0. *
- ****************************************************************************/
-
- static int tryz (void)
- {
- int c, n;
- int cmdzack1flg;
-
- if (_Nozmodem) /* Check for "rb" program name */
- return 0;
-
- for (n = _Zmodem ? 15 : 5; --n >= 0;)
- {
- /* Set buffer length (0) and capability flags. */
-
- _stohdr (0L);
- #ifdef CANBREAK
- _Txhdr[ZF0] = CANFC32 | CANFDX | CANOVIO | CANBRK;
- #else
- _Txhdr[ZF0] = CANFC32 | CANFDX | CANOVIO;
- #endif
- if (_Zctlesc)
- _Txhdr[ZF0] |= TESCCTL;
-
- _zshhdr (tryzhdrtype, _Txhdr);
- if (tryzhdrtype == ZSKIP) /* Don't skip too far */
- tryzhdrtype = ZRINIT; /* CAF 8-21-87 */
-
- again:
- switch (_zgethdr (_Rxhdr, 0))
- {
- case ZRQINIT:
- continue;
-
- case ZEOF:
- continue;
-
- case ZTIMEOUT:
- continue;
-
- case ZFILE:
- _zconv = _Rxhdr[ZF0];
- _zmanag = _Rxhdr[ZF1];
- _ztrans = _Rxhdr[ZF2];
- tryzhdrtype = ZRINIT;
- c = _zrdata (secbuf, KSIZE);
- if (c == GOTCRCW)
- return ZFILE;
-
- _zshhdr (ZNAK, _Txhdr);
- goto again;
-
- case ZSINIT:
- _Zctlesc = TESCCTL & _Rxhdr[ZF0];
- if (_zrdata (_Attn, ZATTNLEN) == GOTCRCW)
- {
- _zshhdr (ZACK, _Txhdr);
- goto again;
- }
-
- _zshhdr (ZNAK, _Txhdr);
- goto again;
-
- case ZFREECNT:
- _stohdr (getfree ());
- _zshhdr (ZACK, _Txhdr);
- goto again;
-
- case ZCOMMAND:
- cmdzack1flg = _Rxhdr[ZF0];
- if (_zrdata (secbuf, KSIZE) == GOTCRCW)
- {
- if (cmdzack1flg & ZCACK1)
- _stohdr (0L);
- else
- {
- if (nocommand)
- _stohdr (0L); /* fake command ok */
- else
- _stohdr ((long) sys2 (secbuf));
-
- }
-
- purgeline (); /* dump impatient questions */
- do
- {
- _zshhdr (ZCOMPL, _Txhdr);
- } while (++_errors < 20 && _zgethdr (_Rxhdr,1) != ZFIN);
-
- ackbibi ();
- if (cmdzack1flg & ZCACK1)
- if (nocommand)
- longjmp (_tohere, -1); /* don't do it */
- else
- exec2 (secbuf);
-
- return ZCOMPL;
- } /* if (_zrdata (secbuf, KSIZE) == GOTCRCW) */
-
- _zshhdr (ZNAK, _Txhdr);
- goto again;
-
- case ZCOMPL:
- goto again;
-
- default:
- continue;
-
- case ZFIN:
- ackbibi ();
- return ZCOMPL;
-
- case ZCAN:
- return ERROR;
- } /* switch (_zgethdr (_Rxhdr, 0)) */
-
- } /* for (n = _Zmodem ? 15 : 5; --n >= 0;) */
-
- return 0;
- } /* static int tryz (void) */
-
-
- /****************************************************************************
- * rzfiles *
- * Receive one or more files with the ZMODEM protocol. *
- ****************************************************************************/
-
- static int rzfiles (void)
- {
- int c;
-
- for (;;)
- {
- switch (c = rzfile ())
- {
- case ZEOF:
- case ZSKIP:
- switch (tryz ())
- {
- case ZCOMPL:
- return OK;
-
- default:
- return ERROR;
-
- case ZFILE:
- break;
- }
-
- continue;
-
- default:
- return c;
-
- case ERROR:
- return ERROR;
- } /* switch (c = rzfile ()) */
-
- } /* for (;;) */
-
- } /* static int rzfiles (void) */
-
-
- /****************************************************************************
- * rzfile *
- * Receive a file with ZMODEM protocol. Assumes file name frame is in *
- * secbuf. *
- ****************************************************************************/
-
- static int rzfile (void)
- {
- int c, n;
- long rxbytes;
- int sent_zm = FALSE; /* TRUE - sent ZMODEM string */
- Eofseen = FALSE;
- if (procheader (secbuf) == ERROR)
- {
- return (tryzhdrtype = ZSKIP);
- }
-
- n = 20;
- rxbytes = 0l;
-
- for (;;)
- {
- _stohdr (rxbytes);
- _zshhdr (ZRPOS, _Txhdr);
-
- nxthdr:
- switch (c = _zgethdr (_Rxhdr, 0))
- {
- default:
- _vfile ("rzfile: _zgethdr returned %d", c);
- return ERROR;
-
- case ZNAK:
- case ZTIMEOUT:
- if ( --n < 0)
- {
- _vfile ("rzfile: _zgethdr returned %d", c);
- return ERROR;
- }
-
- case ZFILE:
- _zrdata (secbuf, KSIZE);
- continue;
-
- case ZEOF:
- if (_rclhdr (_Rxhdr) != rxbytes)
- {
- /*
- * Ignore eof if it's at wrong place - force
- * a timeout because the eof might have gone
- * out before we sent our zrpos.
- */
-
- _errors = 0;
- goto nxthdr;
- }
-
- if (closeit ())
- {
- tryzhdrtype = ZFERR;
- _vfile ("rzfile: closeit returned <> 0");
- return ERROR;
- }
-
- _vfile ("rzfile: normal EOF");
- ++Filcnt;
- return c;
-
- case ERROR: /* Too much garbage in header search
- error */
- if (--n < 0)
- {
- _vfile ("rzfile: _zgethdr returned %d", c);
- return ERROR;
- }
-
- zmputs (_Attn);
- continue;
-
- case ZDATA:
- if (_rclhdr (_Rxhdr) != rxbytes)
- {
- if ( --n < 0)
- {
- return ERROR;
- }
-
- zmputs (_Attn);
- continue;
- }
-
- moredata:
- if (_Verbose > 1)
- {
- (*_do_report) (1, &rxbytes);
- if (!sent_zm)
- {
- sent_zm = TRUE;
- _say ("ZMODEM%s", _Crc32 ? " CRC-32" : "");
- }
-
- }
-
- switch (c = _zrdata (secbuf, KSIZE))
- {
- case ZCAN:
- _vfile ("rzfile: _zgethdr returned %d", c);
- return ERROR;
-
- case ERROR: /* CRC error */
- if (--n < 0)
- {
- _vfile ("rzfile: _zgethdr returned %d", c);
- return ERROR;
- }
-
- zmputs (_Attn);
- continue;
-
- case ZTIMEOUT:
- if (--n < 0)
- {
- _vfile ("rzfile: _zgethdr returned %d", c);
- return ERROR;
- }
-
- continue;
-
- case GOTCRCW:
- n = 20;
- putsec (secbuf, _Rxcount);
- rxbytes += _Rxcount;
- _stohdr (rxbytes);
- _zshhdr (ZACK, _Txhdr);
- _sendline (XON);
- goto nxthdr;
-
- case GOTCRCQ:
- n = 20;
- putsec (secbuf, _Rxcount);
- rxbytes += _Rxcount;
- _stohdr (rxbytes);
- _zshhdr (ZACK, _Txhdr);
- goto moredata;
-
- case GOTCRCG:
- n = 20;
- putsec (secbuf, _Rxcount);
- rxbytes += _Rxcount;
- goto moredata;
-
- case GOTCRCE:
- n = 20;
- putsec (secbuf, _Rxcount);
- rxbytes += _Rxcount;
- goto nxthdr;
- } /* switch (c = _zrdata (secbuf, KSIZE)) */
-
- } /* switch (c = _zgethdr (_Rxhdr, 0)) */
-
- } /* for (;;) */
-
- } /* static int rzfile (void) */
-
-
- /****************************************************************************
- * zmputs *
- * Send a string to the modem, processing for \336 (sleep 1 sec) and \335 *
- * (break signal). *
- ****************************************************************************/
-
- static void zmputs (char *s)
- {
- int c;
-
- while (*s)
- {
- switch (c = *s++)
- {
- case '\336':
- sleep (1);
- continue;
-
- case '\335':
- _sendbrk ();
- continue;
-
- default:
- _sendline (c);
- } /* switch (c = *s++) */
-
- } /* while (*s) */
-
- } /* static void zmputs (char *s) */
-
-
- /****************************************************************************
- * closeit *
- * Close the receive dataset, return OK or ERROR. *
- ****************************************************************************/
-
- static int closeit (void)
- {
- if (close (fout) == -1)
- {
- _zperr_ ("file close ERROR\n");
- return ERROR;
- }
-
- #if 0
- /* Bit fancy for MesS-DOS, what? */
-
- if (Modtime)
- {
- timep[0] = time (NULL);
- timep[1] = Modtime;
- utime (Pathname, timep);
- }
-
- if (Filemode)
- chmod (Pathname, (07777 & Filemode));
- #endif
-
- return OK;
- } /* static int closeit (void) */
-
-
- /****************************************************************************
- * ackbibi *
- * Ack a ZFIN packet, let bygones be bygones. *
- ****************************************************************************/
-
- static void ackbibi (void)
- {
- int n;
-
- _vfile ("ackbibi:");
- Readnum = 1;
- _stohdr (0L);
- for (n = 3; --n >= 0;)
- {
- purgeline ();
- _zshhdr (ZFIN, _Txhdr);
- switch (_readline (100))
- {
- case 'O':
- _readline (1); /* Discard 2nd 'O' */
- _vfile ("ackbibi complete");
- return;
-
- case RCDO:
- return;
-
- case ZTIMEOUT:
- default:
- break;
- } /* switch (_readline (100)) */
-
- } /* for (n = 3; --n >= 0;) */
-
- } /* static void ackbibi (void) */
-
-
- /****************************************************************************
- * sys2 *
- * Strip leading ! if present, do shell escape. *
- ****************************************************************************/
-
- static int sys2 (char *s)
- {
- if (*s == '!')
- ++s;
-
- return system (s);
- } /* static int sys2 (char *s) */
-
-
- /****************************************************************************
- * exec2 *
- * Strip leading '!' if present and do an exec. *
- ****************************************************************************/
-
- static void exec2 (char *s)
- {
- char *comspec; /* -> command.com */
- int result; /* result of exec */
-
- #ifdef DEBUGZ
- _vfile ("exec2: exec %s\n", s);
- #endif
- if (*s == '!')
- ++s;
-
- if ((comspec = getenv ("COMSPEC")) != NULL)
- result = execl (comspec, "command", "/c", s, NULL);
- else
- result = execl ("command", "command", "/c", s, NULL);
-
- if (result == -1)
- perror ("exec2");
-
- } /* static void exec2 (char *s) */
- /* End of rz.c */
-